home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / game / shoot / WarpQuake_src.lha / WarpQuakeSrc / screen.c < prev    next >
C/C++ Source or Header  |  2000-03-02  |  20KB  |  992 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // screen.c -- master for refresh, status bar, console, chat, notify, etc
  21.  
  22. #include "quakedef.h"
  23. #include "r_local.h"
  24.  
  25. // only the refresh window will be updated unless these variables are flagged 
  26. int            scr_copytop;
  27. int            scr_copyeverything;
  28.  
  29. float        scr_con_current;
  30. float        scr_conlines;        // lines of console to display
  31.  
  32. float        oldscreensize, oldfov;
  33. cvar_t        scr_viewsize = {"viewsize","100", true};
  34. cvar_t        scr_fov = {"fov","90"};    // 10 - 170
  35. cvar_t        scr_conspeed = {"scr_conspeed","300"};
  36. cvar_t        scr_centertime = {"scr_centertime","2"};
  37. cvar_t        scr_showram = {"showram","1"};
  38. cvar_t        scr_showturtle = {"showturtle","0"};
  39. cvar_t        scr_showpause = {"showpause","1"};
  40. cvar_t        scr_printspeed = {"scr_printspeed","8"};
  41.  
  42. qboolean    scr_initialized;        // ready to draw
  43.  
  44. qpic_t        *scr_ram;
  45. qpic_t        *scr_net;
  46. qpic_t        *scr_turtle;
  47.  
  48. int            scr_fullupdate;
  49.  
  50. int            clearconsole;
  51. int            clearnotify;
  52.  
  53. viddef_t    vid;                // global video state
  54.  
  55. vrect_t        *pconupdate;
  56. vrect_t        scr_vrect;
  57.  
  58. qboolean    scr_disabled_for_loading;
  59. qboolean    scr_drawloading;
  60. float        scr_disabled_time;
  61. qboolean    scr_skipupdate;
  62.  
  63. qboolean    block_drawing;
  64.  
  65. void SCR_ScreenShot_f (void);
  66.  
  67. /*
  68. ===============================================================================
  69.  
  70. CENTER PRINTING
  71.  
  72. ===============================================================================
  73. */
  74.  
  75. char        scr_centerstring[1024];
  76. float        scr_centertime_start;    // for slow victory printing
  77. float        scr_centertime_off;
  78. int            scr_center_lines;
  79. int            scr_erase_lines;
  80. int            scr_erase_center;
  81.  
  82. /*
  83. ==============
  84. SCR_CenterPrint
  85.  
  86. Called for important messages that should stay in the center of the screen
  87. for a few moments
  88. ==============
  89. */
  90. void SCR_CenterPrint (char *str)
  91. {
  92.     strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1);
  93.     scr_centertime_off = scr_centertime.value;
  94.     scr_centertime_start = cl.time;
  95.  
  96. // count the number of lines for centering
  97.     scr_center_lines = 1;
  98.     while (*str)
  99.     {
  100.         if (*str == '\n')
  101.             scr_center_lines++;
  102.         str++;
  103.     }
  104. }
  105.  
  106. void SCR_EraseCenterString (void)
  107. {
  108.     int        y;
  109.  
  110.     if (scr_erase_center++ > vid.numpages)
  111.     {
  112.         scr_erase_lines = 0;
  113.         return;
  114.     }
  115.  
  116.     if (scr_center_lines <= 4)
  117.         y = vid.height*0.35;
  118.     else
  119.         y = 48;
  120.  
  121.     scr_copytop = 1;
  122.     Draw_TileClear (0, y,vid.width, 8*scr_erase_lines);
  123. }
  124.  
  125. void SCR_DrawCenterString (void)
  126. {
  127.     char    *start;
  128.     int        l;
  129.     int        j;
  130.     int        x, y;
  131.     int        remaining;
  132.  
  133. // the finale prints the characters one at a time
  134.     if (cl.intermission)
  135.         remaining = scr_printspeed.value * (cl.time - scr_centertime_start);
  136.     else
  137.         remaining = 9999;
  138.  
  139.     scr_erase_center = 0;
  140.     start = scr_centerstring;
  141.  
  142.     if (scr_center_lines <= 4)
  143.         y = vid.height*0.35;
  144.     else
  145.         y = 48;
  146.  
  147.     do    
  148.     {
  149.     // scan the width of the line
  150.         for (l=0 ; l<40 ; l++)
  151.             if (start[l] == '\n' || !start[l])
  152.                 break;
  153.         x = (vid.width - l*8)/2;
  154.         for (j=0 ; j<l ; j++, x+=8)
  155.         {
  156.             Draw_Character (x, y, start[j]);    
  157.             if (!remaining--)
  158.                 return;
  159.         }
  160.             
  161.         y += 8;
  162.  
  163.         while (*start && *start != '\n')
  164.             start++;
  165.  
  166.         if (!*start)
  167.             break;
  168.         start++;        // skip the \n
  169.     } while (1);
  170. }
  171.  
  172. void SCR_CheckDrawCenterString (void)
  173. {
  174.     scr_copytop = 1;
  175.     if (scr_center_lines > scr_erase_lines)
  176.         scr_erase_lines = scr_center_lines;
  177.  
  178.     scr_centertime_off -= host_frametime;
  179.     
  180.     if (scr_centertime_off <= 0 && !cl.intermission)
  181.         return;
  182.     if (key_dest != key_game)
  183.         return;
  184.  
  185.     SCR_DrawCenterString ();
  186. }
  187.  
  188. //=============================================================================
  189.  
  190. /*
  191. ====================
  192. CalcFov
  193. ====================
  194. */
  195. float CalcFov (float fov_x, float width, float height)
  196. {
  197.         float   a;
  198.         float   x;
  199.  
  200.         if (fov_x < 1 || fov_x > 179)
  201.                 Sys_Error ("Bad fov: %f", fov_x);
  202.  
  203.         x = width/tan(fov_x/360*M_PI);
  204.  
  205.         a = atan (height/x);
  206.  
  207.         a = a*360/M_PI;
  208.  
  209.         return a;
  210. }
  211.  
  212. /*
  213. =================
  214. SCR_CalcRefdef
  215.  
  216. Must be called whenever vid changes
  217. Internal use only
  218. =================
  219. */
  220. static void SCR_CalcRefdef (void)
  221. {
  222.     vrect_t        vrect;
  223.     float        size;
  224.  
  225.     scr_fullupdate = 0;        // force a background redraw
  226.     vid.recalc_refdef = 0;
  227.  
  228. // force the status bar to redraw
  229.     Sbar_Changed ();
  230.  
  231. //========================================
  232.     
  233. // bound viewsize
  234.     if (scr_viewsize.value < 30)
  235.         Cvar_Set ("viewsize","30");
  236.     if (scr_viewsize.value > 120)
  237.         Cvar_Set ("viewsize","120");
  238.  
  239. // bound field of view
  240.     if (scr_fov.value < 10)
  241.         Cvar_Set ("fov","10");
  242.     if (scr_fov.value > 170)
  243.         Cvar_Set ("fov","170");
  244.  
  245.     r_refdef.fov_x = scr_fov.value;
  246.     r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height);
  247.  
  248. // intermission is always full screen    
  249.     if (cl.intermission)
  250.         size = 120;
  251.     else
  252.         size = scr_viewsize.value;
  253.  
  254.     if (size >= 120)
  255.         sb_lines = 0;        // no status bar at all
  256.     else if (size >= 110)
  257.         sb_lines = 24;        // no inventory
  258.     else
  259.         sb_lines = 24+16+8;
  260.  
  261. // these calculations mirror those in R_Init() for r_refdef, but take no
  262. // account of water warping
  263.     vrect.x = 0;
  264.     vrect.y = 0;
  265.     vrect.width = vid.width;
  266.     vrect.height = vid.height;
  267.  
  268.     R_SetVrect (&vrect, &scr_vrect, sb_lines);
  269.  
  270. // guard against going from one mode to another that's less than half the
  271. // vertical resolution
  272.     if (scr_con_current > vid.height)
  273.         scr_con_current = vid.height;
  274.  
  275. // notify the refresh of the change
  276.     R_ViewChanged (&vrect, sb_lines, vid.aspect);
  277. }
  278.  
  279.  
  280. /*
  281. =================
  282. SCR_SizeUp_f
  283.  
  284. Keybinding command
  285. =================
  286. */
  287. void SCR_SizeUp_f (void)
  288. {
  289.     Cvar_SetValue ("viewsize",scr_viewsize.value+10);
  290.     vid.recalc_refdef = 1;
  291. }
  292.  
  293.  
  294. /*
  295. =================
  296. SCR_SizeDown_f
  297.  
  298. Keybinding command
  299. =================
  300. */
  301. void SCR_SizeDown_f (void)
  302. {
  303.     Cvar_SetValue ("viewsize",scr_viewsize.value-10);
  304.     vid.recalc_refdef = 1;
  305. }
  306.  
  307. //============================================================================
  308.  
  309. /*
  310. ==================
  311. SCR_Init
  312. ==================
  313. */
  314. void SCR_Init (void)
  315. {
  316.     Cvar_RegisterVariable (&scr_fov);
  317.     Cvar_RegisterVariable (&scr_viewsize);
  318.     Cvar_RegisterVariable (&scr_conspeed);
  319.     Cvar_RegisterVariable (&scr_showram);
  320.     Cvar_RegisterVariable (&scr_showturtle);
  321.     Cvar_RegisterVariable (&scr_showpause);
  322.     Cvar_RegisterVariable (&scr_centertime);
  323.     Cvar_RegisterVariable (&scr_printspeed);
  324.  
  325. //
  326. // register our commands
  327. //
  328.     Cmd_AddCommand ("screenshot",SCR_ScreenShot_f);
  329.     Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
  330.     Cmd_AddCommand ("sizedown",SCR_SizeDown_f);
  331.  
  332.     scr_ram = Draw_PicFromWad ("ram");
  333.     scr_net = Draw_PicFromWad ("net");
  334.     scr_turtle = Draw_PicFromWad ("turtle");
  335.  
  336.     scr_initialized = true;
  337. }
  338.  
  339.  
  340.  
  341. /*
  342. ==============
  343. SCR_DrawRam
  344. ==============
  345. */
  346. void SCR_DrawRam (void)
  347. {
  348.     if (!scr_showram.value)
  349.         return;
  350.  
  351.     if (!r_cache_thrash)
  352.         return;
  353.  
  354.     Draw_Pic (scr_vrect.x+32, scr_vrect.y, scr_ram);
  355. }
  356.  
  357. /*
  358. ==============
  359. SCR_DrawTurtle
  360. ==============
  361. */
  362. void SCR_DrawTurtle (void)
  363. {
  364.     static int    count;
  365.     
  366.     if (!scr_showturtle.value)
  367.         return;
  368.  
  369.     if (host_frametime < 0.1)
  370.     {
  371.         count = 0;
  372.         return;
  373.     }
  374.  
  375.     count++;
  376.     if (count < 3)
  377.         return;
  378.  
  379.     Draw_Pic (scr_vrect.x, scr_vrect.y, scr_turtle);
  380. }
  381.  
  382. /*
  383. ==============
  384. SCR_DrawNet
  385. ==============
  386. */
  387. void SCR_DrawNet (void)
  388. {
  389.     if (realtime - cl.last_received_message < 0.3)
  390.         return;
  391.     if (cls.demoplayback)
  392.         return;
  393.  
  394.     Draw_Pic (scr_vrect.x+64, scr_vrect.y, scr_net);
  395. }
  396.  
  397. /*
  398. ==============
  399. DrawPause
  400. ==============
  401. */
  402. void SCR_DrawPause (void)
  403. {
  404.     qpic_t    *pic;
  405.  
  406.     if (!scr_showpause.value)        // turn off for screenshots
  407.         return;
  408.  
  409.     if (!cl.paused)
  410.         return;
  411.  
  412.     pic = Draw_CachePic ("gfx/pause.lmp");
  413.     Draw_Pic ( (vid.width - pic->width)/2, 
  414.         (vid.height - 48 - pic->height)/2, pic);
  415. }
  416.  
  417.  
  418.  
  419. /*
  420. ==============
  421. SCR_DrawLoading
  422. ==============
  423. */
  424. void SCR_DrawLoading (void)
  425. {
  426.     qpic_t    *pic;
  427.  
  428.     if (!scr_drawloading)
  429.         return;
  430.         
  431.     pic = Draw_CachePic ("gfx/loading.lmp");
  432.     Draw_Pic ( (vid.width - pic->width)/2, 
  433.         (vid.height - 48 - pic->height)/2, pic);
  434. }
  435.  
  436.  
  437.  
  438. //=============================================================================
  439.  
  440.  
  441. /*
  442. ==================
  443. SCR_SetUpToDrawConsole
  444. ==================
  445. */
  446. void SCR_SetUpToDrawConsole (void)
  447. {
  448.     Con_CheckResize ();
  449.     
  450.     if (scr_drawloading)
  451.         return;        // never a console with loading plaque
  452.         
  453. // decide on the height of the console
  454.     con_forcedup = !cl.worldmodel || cls.signon != SIGNONS;
  455.  
  456.     if (con_forcedup)
  457.     {
  458.         scr_conlines = vid.height;        // full screen
  459.         scr_con_current = scr_conlines;
  460.     }
  461.     else if (key_dest == key_console)
  462.         scr_conlines = vid.height/2;    // half screen
  463.     else
  464.         scr_conlines = 0;                // none visible
  465.     
  466.     if (scr_conlines < scr_con_current)
  467.     {
  468.         scr_con_current -= scr_conspeed.value*host_frametime;
  469.         if (scr_conlines > scr_con_current)
  470.             scr_con_current = scr_conlines;
  471.  
  472.     }
  473.     else if (scr_conlines > scr_con_current)
  474.     {
  475.         scr_con_current += scr_conspeed.value*host_frametime;
  476.         if (scr_conlines < scr_con_current)
  477.             scr_con_current = scr_conlines;
  478.     }
  479.  
  480.     if (clearconsole++ < vid.numpages)
  481.     {
  482.         scr_copytop = 1;
  483.         Draw_TileClear (0,(int)scr_con_current,vid.width, vid.height - (int)scr_con_current);
  484.         Sbar_Changed ();
  485.     }
  486.     else if (clearnotify++ < vid.numpages)
  487.     {
  488.         scr_copytop = 1;
  489.         Draw_TileClear (0,0,vid.width, con_notifylines);
  490.     }
  491.     else
  492.         con_notifylines = 0;
  493. }
  494.     
  495. /*
  496. ==================
  497. SCR_DrawConsole
  498. ==================
  499. */
  500. void SCR_DrawConsole (void)
  501. {
  502.     if (scr_con_current)
  503.     {
  504.         scr_copyeverything = 1;
  505.         Con_DrawConsole (scr_con_current, true);
  506.         clearconsole = 0;
  507.     }
  508.     else
  509.     {
  510.         if (key_dest == key_game || key_dest == key_message)
  511.             Con_DrawNotify ();    // only draw notify in game
  512.     }
  513. }
  514.  
  515.  
  516. /* 
  517. ============================================================================== 
  518.  
  519.                         SCREEN SHOTS 
  520.  
  521. ============================================================================== 
  522. */ 
  523.  
  524.  
  525. typedef struct
  526. {
  527.     char    manufacturer;
  528.     char    version;
  529.     char    encoding;
  530.     char    bits_per_pixel;
  531.     unsigned short    xmin,ymin,xmax,ymax;
  532.     unsigned short    hres,vres;
  533.     unsigned char    palette[48];
  534.     char    reserved;
  535.     char    color_planes;
  536.     unsigned short    bytes_per_line;
  537.     unsigned short    palette_type;
  538.     char    filler[58];
  539.     unsigned char    data;            // unbounded
  540. } pcx_t;
  541.  
  542. /* 
  543. ============== 
  544. WritePCXfile 
  545. ============== 
  546. */ 
  547. void WritePCXfile (char *filename, byte *data, int width, int height,
  548.     int rowbytes, byte *palette) 
  549. {
  550.     int        i, j, length;
  551.     pcx_t    *pcx;
  552.     byte        *pack;
  553.       
  554.     pcx = Hunk_TempAlloc (width*height*2+1000);
  555.     if (pcx == NULL)
  556.     {
  557.         Con_Printf("SCR_ScreenShot_f: not enough memory\n");
  558.         return;
  559.     } 
  560.  
  561.     pcx->manufacturer = 0x0a;    // PCX id
  562.     pcx->version = 5;            // 256 color
  563.      pcx->encoding = 1;        // uncompressed
  564.     pcx->bits_per_pixel = 8;        // 256 color
  565.     pcx->xmin = 0;
  566.     pcx->ymin = 0;
  567.     pcx->xmax = LittleShort((short)(width-1));
  568.     pcx->ymax = LittleShort((short)(height-1));
  569.     pcx->hres = LittleShort((short)width);
  570.     pcx->vres = LittleShort((short)height);
  571.     Q_memset (pcx->palette,0,sizeof(pcx->palette));
  572.     pcx->color_planes = 1;        // chunky image
  573.     pcx->bytes_per_line = LittleShort((short)width);
  574.     pcx->palette_type = LittleShort(2);        // not a grey scale
  575.     Q_memset (pcx->filler,0,sizeof(pcx->filler));
  576.  
  577. // pack the image
  578.     pack = &pcx->data;
  579.     
  580.     for (i=0 ; i<height ; i++)
  581.     {
  582.         for (j=0 ; j<width ; j++)
  583.         {
  584.             if ( (*data & 0xc0) != 0xc0)
  585.                 *pack++ = *data++;
  586.             else
  587.             {
  588.                 *pack++ = 0xc1;
  589.                 *pack++ = *data++;
  590.             }
  591.         }
  592.  
  593.         data += rowbytes - width;
  594.     }
  595.             
  596. // write the palette
  597.     *pack++ = 0x0c;    // palette ID byte
  598.     for (i=0 ; i<768 ; i++)
  599.         *pack++ = *palette++;
  600.         
  601. // write output file 
  602.     length = pack - (byte *)pcx;
  603.     COM_WriteFile (filename, pcx, length);
  604.  
  605.  
  606.  
  607. /* 
  608. ================== 
  609. SCR_ScreenShot_f
  610. ================== 
  611. */  
  612. void SCR_ScreenShot_f (void) 
  613.     int     i; 
  614.     char        pcxname[80]; 
  615.     char        checkname[MAX_OSPATH];
  616.  
  617. // 
  618. // find a file name to save it to 
  619. // 
  620.     strcpy(pcxname,"quake00.pcx");
  621.         
  622.     for (i=0 ; i<=99 ; i++) 
  623.     { 
  624.         pcxname[5] = i/10 + '0'; 
  625.         pcxname[6] = i%10 + '0'; 
  626.         sprintf (checkname, "%s/%s", com_gamedir, pcxname);
  627.         if (Sys_FileTime(checkname) == -1)
  628.             break;    // file doesn't exist
  629.     } 
  630.     if (i==100) 
  631.     {
  632.         Con_Printf ("SCR_ScreenShot_f: Couldn't create a PCX file\n"); 
  633.         return;
  634.      }
  635.  
  636. // 
  637. // save the pcx file 
  638. // 
  639.     D_EnableBackBufferAccess ();    // enable direct drawing of console to back
  640.                                     //  buffer
  641.  
  642.     WritePCXfile (pcxname, vid.buffer, vid.width, vid.height, vid.rowbytes,
  643.                   host_basepal);
  644.  
  645.     D_DisableBackBufferAccess ();    // for adapters that can't stay mapped in
  646.                                     //  for linear writes all the time
  647.  
  648.     Con_Printf ("Wrote %s\n", pcxname);
  649.  
  650.  
  651. //=============================================================================
  652.  
  653.  
  654. /*
  655. ===============
  656. SCR_BeginLoadingPlaque
  657.  
  658. ================
  659. */
  660. void SCR_BeginLoadingPlaque (void)
  661. {
  662.     S_StopAllSounds (true);
  663.  
  664.     if (cls.state != ca_connected)
  665.         return;
  666.     if (cls.signon != SIGNONS)
  667.         return;
  668.     
  669. // redraw with no console and the loading plaque
  670.     Con_ClearNotify ();
  671.     scr_centertime_off = 0;
  672.     scr_con_current = 0;
  673.  
  674.     scr_drawloading = true;
  675.     scr_fullupdate = 0;
  676.     Sbar_Changed ();
  677.     SCR_UpdateScreen ();
  678.     scr_drawloading = false;
  679.  
  680.     scr_disabled_for_loading = true;
  681.     scr_disabled_time = realtime;
  682.     scr_fullupdate = 0;
  683. }
  684.  
  685. /*
  686. ===============
  687. SCR_EndLoadingPlaque
  688.  
  689. ================
  690. */
  691. void SCR_EndLoadingPlaque (void)
  692. {
  693.     scr_disabled_for_loading = false;
  694.     scr_fullupdate = 0;
  695.     Con_ClearNotify ();
  696. }
  697.  
  698. //=============================================================================
  699.  
  700. char    *scr_notifystring;
  701. qboolean    scr_drawdialog;
  702.  
  703. void SCR_DrawNotifyString (void)
  704. {
  705.     char    *start;
  706.     int        l;
  707.     int        j;
  708.     int        x, y;
  709.  
  710.     start = scr_notifystring;
  711.  
  712.     y = vid.height*0.35;
  713.  
  714.     do    
  715.     {
  716.     // scan the width of the line
  717.         for (l=0 ; l<40 ; l++)
  718.             if (start[l] == '\n' || !start[l])
  719.                 break;
  720.         x = (vid.width - l*8)/2;
  721.         for (j=0 ; j<l ; j++, x+=8)
  722.             Draw_Character (x, y, start[j]);    
  723.             
  724.         y += 8;
  725.  
  726.         while (*start && *start != '\n')
  727.             start++;
  728.  
  729.         if (!*start)
  730.             break;
  731.         start++;        // skip the \n
  732.     } while (1);
  733. }
  734.  
  735. /*
  736. ==================
  737. SCR_ModalMessage
  738.  
  739. Displays a text string in the center of the screen and waits for a Y or N
  740. keypress.  
  741. ==================
  742. */
  743. int SCR_ModalMessage (char *text)
  744. {
  745.     if (cls.state == ca_dedicated)
  746.         return true;
  747.  
  748.     scr_notifystring = text;
  749.  
  750. // draw a fresh screen
  751.     scr_fullupdate = 0;
  752.     scr_drawdialog = true;
  753.     SCR_UpdateScreen ();
  754.     scr_drawdialog = false;
  755.     
  756.     S_ClearBuffer ();        // so dma doesn't loop current sound
  757.  
  758.     do
  759.     {
  760.         key_count = -1;        // wait for a key down and up
  761.         Sys_SendKeyEvents ();
  762.     } while (key_lastpress != 'y' && key_lastpress != 'n' && key_lastpress != K_ESCAPE);
  763.  
  764.     scr_fullupdate = 0;
  765.     SCR_UpdateScreen ();
  766.  
  767.     return key_lastpress == 'y';
  768. }
  769.  
  770.  
  771. //=============================================================================
  772.  
  773. /*
  774. ===============
  775. SCR_BringDownConsole
  776.  
  777. Brings the console down and fades the palettes back to normal
  778. ================
  779. */
  780. void SCR_BringDownConsole (void)
  781. {
  782.     int        i;
  783.     
  784.     scr_centertime_off = 0;
  785.     
  786.     for (i=0 ; i<20 && scr_conlines != scr_con_current ; i++)
  787.         SCR_UpdateScreen ();
  788.  
  789.     cl.cshifts[0].percent = 0;        // no area contents palette on next frame
  790.     VID_SetPalette (host_basepal);
  791. }
  792.  
  793.  
  794. /*
  795. ==================
  796. SCR_UpdateScreen
  797.  
  798. This is called every frame, and can also be called explicitly to flush
  799. text to the screen.
  800.  
  801. WARNING: be very careful calling this from elsewhere, because the refresh
  802. needs almost the entire 256k of stack space!
  803. ==================
  804. */
  805. void SCR_UpdateScreen (void)
  806. {
  807.     static float    oldscr_viewsize;
  808.     static float    oldlcd_x;
  809.     vrect_t        vrect;
  810.     
  811.     if (scr_skipupdate || block_drawing)
  812.         return;
  813.  
  814.     scr_copytop = 0;
  815.     scr_copyeverything = 0;
  816.  
  817.     if (scr_disabled_for_loading)
  818.     {
  819.         if (realtime - scr_disabled_time > 60)
  820.         {
  821.             scr_disabled_for_loading = false;
  822.             Con_Printf ("load failed.\n");
  823.         }
  824.         else
  825.             return;
  826.     }
  827.  
  828.     if (cls.state == ca_dedicated)
  829.         return;                // stdout only
  830.  
  831.     if (!scr_initialized || !con_initialized)
  832.         return;                // not initialized yet
  833.  
  834.     if (scr_viewsize.value != oldscr_viewsize)
  835.     {
  836.         oldscr_viewsize = scr_viewsize.value;
  837.         vid.recalc_refdef = 1;
  838.     }
  839.     
  840. //
  841. // check for vid changes
  842. //
  843.     if (oldfov != scr_fov.value)
  844.     {
  845.         oldfov = scr_fov.value;
  846.         vid.recalc_refdef = true;
  847.     }
  848.     
  849.     if (oldlcd_x != lcd_x.value)
  850.     {
  851.         oldlcd_x = lcd_x.value;
  852.         vid.recalc_refdef = true;
  853.     }
  854.     
  855.     if (oldscreensize != scr_viewsize.value)
  856.     {
  857.         oldscreensize = scr_viewsize.value;
  858.         vid.recalc_refdef = true;
  859.     }
  860.     
  861.     if (vid.recalc_refdef)
  862.     {
  863.     // something changed, so reorder the screen
  864.         SCR_CalcRefdef ();
  865.     }
  866.  
  867. //
  868. // do 3D refresh drawing, and then update the screen
  869. //
  870.     D_EnableBackBufferAccess ();    // of all overlay stuff if drawing directly
  871.  
  872.     if (scr_fullupdate++ < vid.numpages)
  873.     {    // clear the entire screen
  874.         scr_copyeverything = 1;
  875.         Draw_TileClear (0,0,vid.width,vid.height);
  876.         Sbar_Changed ();
  877.     }
  878.  
  879.     pconupdate = NULL;
  880.  
  881.  
  882.     SCR_SetUpToDrawConsole ();
  883.     SCR_EraseCenterString ();
  884.  
  885.     D_DisableBackBufferAccess ();    // for adapters that can't stay mapped in
  886.                                     //  for linear writes all the time
  887.  
  888.     VID_LockBuffer ();
  889.  
  890.     V_RenderView ();
  891.  
  892.     VID_UnlockBuffer ();
  893.  
  894.     D_EnableBackBufferAccess ();    // of all overlay stuff if drawing directly
  895.  
  896.     if (scr_drawdialog)
  897.     {
  898.         Sbar_Draw ();
  899.         Draw_FadeScreen ();
  900.         SCR_DrawNotifyString ();
  901.         scr_copyeverything = true;
  902.     }
  903.     else if (scr_drawloading)
  904.     {
  905.         SCR_DrawLoading ();
  906.         Sbar_Draw ();
  907.     }
  908.     else if (cl.intermission == 1 && key_dest == key_game)
  909.     {
  910.         Sbar_IntermissionOverlay ();
  911.     }
  912.     else if (cl.intermission == 2 && key_dest == key_game)
  913.     {
  914.         Sbar_FinaleOverlay ();
  915.         SCR_CheckDrawCenterString ();
  916.     }
  917.     else if (cl.intermission == 3 && key_dest == key_game)
  918.     {
  919.         SCR_CheckDrawCenterString ();
  920.     }
  921.     else
  922.     {
  923.         SCR_DrawRam ();
  924.         SCR_DrawNet ();
  925.         SCR_DrawTurtle ();
  926.         SCR_DrawPause ();
  927.         SCR_CheckDrawCenterString ();
  928.         Sbar_Draw ();
  929.         SCR_DrawConsole ();
  930.         M_Draw ();
  931.     }
  932.  
  933.     D_DisableBackBufferAccess ();    // for adapters that can't stay mapped in
  934.                                     //  for linear writes all the time
  935.     if (pconupdate)
  936.     {
  937.         D_UpdateRects (pconupdate);
  938.     }
  939.  
  940.     V_UpdatePalette ();
  941.  
  942. //
  943. // update one of three areas
  944. //
  945.  
  946.     if (scr_copyeverything)
  947.     {
  948.         vrect.x = 0;
  949.         vrect.y = 0;
  950.         vrect.width = vid.width;
  951.         vrect.height = vid.height;
  952.         vrect.pnext = 0;
  953.     
  954.         VID_Update (&vrect);
  955.     }
  956.     else if (scr_copytop)
  957.     {
  958.         vrect.x = 0;
  959.         vrect.y = 0;
  960.         vrect.width = vid.width;
  961.         vrect.height = vid.height - sb_lines;
  962.         vrect.pnext = 0;
  963.     
  964.         VID_Update (&vrect);
  965.     }    
  966.     else
  967.     {
  968.         vrect.x = scr_vrect.x;
  969.         vrect.y = scr_vrect.y;
  970.         vrect.width = scr_vrect.width;
  971.         vrect.height = scr_vrect.height;
  972.         vrect.pnext = 0;
  973.     
  974.         VID_Update (&vrect);
  975.     }
  976. }
  977.  
  978.  
  979. /*
  980. ==================
  981. SCR_UpdateWholeScreen
  982. ==================
  983. */
  984. void SCR_UpdateWholeScreen (void)
  985. {
  986.     scr_fullupdate = 0;
  987.     SCR_UpdateScreen ();
  988. }
  989.